const { run, network, config } = require("hardhat")
const { ethers, keccak256 } = require("ethers");
const { expect, AssertionError } = require("chai");
const { bytesToHex, hexToBytes } = require("ethereum-cryptography/utils");
const {
  parseSignedTransaction
} = require('../../scripts/utils/transactionParser');

const {
  createEip1559Transaction
} = require('../../scripts/utils/transactionCreator');

describe("Send Raw Transaction", function () {

  // 存储部署后的合约地址
  let contractAddress;
  // 存储编译后的合约信息
  let contractArtifact;
  // rpc provider
  let provider;
  // 私钥
  let privateKey;

  let wallet;

  before(async function () {

    // 初始化参数
    const chainId = network.config.chainId;
    const url = network.config.url;
    const name = network.name;
    // 打印网络信息
    // console.debug(" ### ===> network", network);
    let privateKey = config.accounts[0];
    // === 钱包 ===  
    let wallet = new ethers.Wallet(privateKey, null);
    let accountAddress = wallet.address;
    console.log(" ### 交易签名私钥 ===>:", privateKey);
    console.log(" ### 交易签名地址 ===>:", wallet.address);

    // 编译合约
    const contractName = "Empty";
    console.log("编译合约:", contractName);
    await run("compile");
    contractArtifact = require(`${config.paths.artifacts}/contracts/${contractName}.sol/${contractName}.json`);
    console.log("合约编译成功");

    // 创建合约ABI接口
    contractBytecode = new ethers.Interface(contractArtifact.abi).encodeFunctionData("emitEvent", []);
    contractAbi = contractArtifact.abi;
    // emitEvent接口abi编码
    emitEventData = new ethers.Interface(contractAbi).encodeFunctionData("emitEvent", []);

    // === rpc provider ===  
    provider = new ethers.JsonRpcProvider(url, { chainId: chainId, name: name }, { staticNetwork: true });

    accountNonce = await provider.getTransactionCount(accountAddress);
    console.log(" ### ===> 发送交易账户nonce:", accountNonce);
  });


  describe("部署合约", function () {
    it("Should set the right unlockTime", async function () {

    });

    it("Should set the right owner", async function () {

    });
  });

  describe("调用合约", function () {
    it("Should set the right unlockTime", async function () {

    });

    it("Should set the right owner", async function () {

    });
  });

  // chainId, nonce, feeData, gasLimit, from, to, value, data

  // 场景1: chainId
  describe("chainId Case", function () {

    it("chainId: 值不匹配", async function () {

    });

    it("chainId: null", async function () {

    });

    it("chainId: undefined", async function () {

    });

    it("chainId: 负数", async function () {

    });

    it("chainId: 字符串", async function () {
      // 空字符串： ""
      // 包含空格的字符串： " 1 ", "main net"
      // 非 UTF - 8 字符的字符串： 例如包含中文、日文等字符的字符串
      // 非数字字符串： "abc", "123abc"
    });

    it("chainId: 浮点数", async function () {

    });

    it("chainId: BigInt", async function () {
      // BigInt 的正数
      // BigInt 的负数(虽然不常见)
      // 非常大的 BigInt 值，超出 Number 的安全范围
    });

    it("chainId: 未知的大型 chainId", async function () {
      const largeChainIds = [
        Number.MAX_VALUE,  // 最大可能数值
        10000000,          // 远超已知网络的 chainId
        999999999
      ];

      for (const chainId of largeChainIds) {
      }
    });

    it("chainId: 极限边界值", async function () {
      const boundaryChainIds = [
        0,              // 零
        Number.MAX_SAFE_INTEGER,  // 最大安全整数
        Number.MIN_SAFE_INTEGER,  // 最小安全整数
        2 ** 53,        // 超出安全整数范围
        -2 ** 53        // 负超出安全整数范围
      ];

      for (const chainId of boundaryChainIds) {
      }
    });

    //其他类型 测试传入非数字的 NaN、Infinity 和 -Infinity。
    it("chainId: NaN", async function () {

    });

    it("chainId: Infinity", async function () {

    });
  });

  // 场景: Nonce
  describe("Nonce场景", function () {

    //     浮点数 nonce：验证浮点数作为 nonce 是否会被正确拒绝。
    // 极端边界值：测试超出安全整数范围的 nonce 值。
    // 特殊字符串数字：检查各种特殊格式的数字字符串。
    // BigInt 类型：验证 BigInt 类型的 nonce 是否被正确处理。
    // NaN 和 Infinity：测试特殊的数学常量。
    // 大量连续 nonce：验证大量连续 nonce 的处理能力。
    // 随机 nonce 值：通过随机生成 nonce 值来测试系统的健壮性。

    it("Nonce回绕", async function () {

    });

    it("Nonce跳跃", async function () {

    });

    it("Nonce: 零值", async function () {

    });

    it("Nonce非法: 负数", async function () {

    });

    it("Nonce非法: 字符串", async function () {

    });

    it("Nonce非法: 浮点数", async function () {

    });

    it("Nonce非法: BigInt", async function () {

    });

    it("Nonce非法: NaN", async function () {

    });

    it("Nonce非法: Infinity", async function () {

    });

    it("Nonce非法: 重放交易攻击", async function () {

    });

    it("Nonce非法: null", async function () {

    });

    it("Nonce非法: undefined", async function () {

    });

    it("Nonce非法: 数组", async function () {

    });

    it("Nonce非法: 对象", async function () {

    });
  });

  describe("非法Value", function () {
    // 正常的转账金额
    // 余额不足测试
    // 负数值测试
    /**
     * ethers.parseEther('-0.01'),
            ethers.parseEther('-1')
     */
    //极限值测试
    /*
    const extremeValues = [
      BigInt(2) ** BigInt(256) - BigInt(1),  // 最大 256 位整数
      ethers.MaxUint256,                     // 以太坊最大可表示值
  ];
  */
    // 非数值类型测试
    /*
    const invalidTypes = [
      null,
      undefined,
      "100",           // 字符串
      [100],           // 数组
      { value: 100 },  // 对象
      NaN,
      Infinity,
      -Infinity
    ];
    */
    // 浮点数值测试
    /*
    const floatValues = [
      0.1,
      1.5,
      -0.5
    ];
    */
    // 科学计数法
    /*
    const scientificNotationValues = [
     1e18,    // 1 ETH
     5e-18,   // 很小的值
     -1e18    // 负数科学计数法
 ];
 */
    // BigInt
    /*
    const bigIntValues = [
      BigInt(100),
      BigInt('-100'),
      BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)
    ];
    */
    // 特殊字符串
    /*
    const specialStringValues = [
      "100",        // 数字字符串
      " 100 ",      // 带空格的数字字符串
      "0x64",       // 十六进制字符串
      "1e18"        // 科学计数法字符串
  ];
  */
    // 精度测试
    /*
    const precisionValues = [
      ethers.parseEther('0.000000000000000001'),  // 极小精度
      ethers.parseEther('1.000000000000000001')   // 超出精度的值
  ];*/



    //  零值转账
    /**
     * const transaction = {
            chainId: 1,
            nonce: 0,
            to: ethers.getAddress('0x1234567890123456789012345678901234567890'),
            value: ethers.parseEther('0'),
            gasLimit: 21000,
            maxFeePerGas: ethers.parseUnits('20', 'gwei'),
            maxPriorityFeePerGas: ethers.parseUnits('2', 'gwei'),
            data: '0x'
        };
     */
  });
});